package mse.tx.arch.pipe.systemC;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import mse.tx.arch.pipe.framework.FilterFramework;
import mse.tx.arch.pipe.framework.IConfigurable;

public class FileSrcFilter extends FilterFramework implements IConfigurable {

	//  default value of file name
	private String fileName = "FlightData.dat";
	
	/**
	 * Constructor method which initializes normal output port
	 */
	
	public FileSrcFilter() {
		addOutputPortByName("output");
	}
	
	/**
	 * Constructor method which initializes normal output port
	 * 
	 * @param name of file that this filter reads
	 */
	
	public FileSrcFilter(String fileName) {
		this.fileName = fileName;
		addOutputPortByName("output");
	}

	public void run() {
		// Number of bytes read from the input file.
		int bytesread = 0; 
		// Number of bytes written to the stream.
		int byteswritten = 0; 
		// File stream reference.
		DataInputStream in = null;
		// The byte of data read from the file
		byte databyte = 0; 

		try {
			/***********************************************************************************
			 * Here we open the file and write a message to the terminal.
			 ***********************************************************************************/

			in = new DataInputStream(new FileInputStream(fileName));
			System.out.println("\n" + this.getName()
					+ "::Source reading file...");

			/***********************************************************************************
			 * Here we read the data from the file and send it out the filter's
			 * output port one byte at a time. The loop stops when it encounters
			 * an EOFExecption.
			 ***********************************************************************************/

			while (true) {
				databyte = in.readByte();
				bytesread++;

				writeFilterOutputPort("output", databyte);
				byteswritten++;

			} // while

		} // try

		/***********************************************************************************
		 * The following exception is raised when we hit the end of input file.
		 * Once we reach this point, we close the input file, close the filter
		 * ports and exit.
		 ***********************************************************************************/

		catch (EOFException eoferr) {
			System.out.println("\n" + this.getName()
					+ ":End of file reached...");

		} // catch

		/***********************************************************************************
		 * The following exception is raised should we have a problem openinging
		 * the file.
		 ***********************************************************************************/

		catch (IOException iox) {
			System.out.println("\n" + this.getName()
					+ "::Problem reading input data file::" + iox);

		} // catch
		finally {
			try {
				// close source file
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			closePorts();
		}
		System.out.println("\n" + this.getName()
				+ "::Read file complete, bytes read::" + bytesread
				+ " bytes written: " + byteswritten);

	} // run

	/**
	 * This method allows that filename can be set via property file
	 */
	@Override
	public void setConfiguration(Properties props) {
		if (props != null) {
			setFilename(props.getProperty("filename"));
		}
	}

	/**
	 * This method allow developers change file name
	 * 
	 * @param name of file that this filter read
	 */
	public void setFilename(String fileName) {
		if (fileName != null)
			this.fileName = fileName;
	}

} // SourceFilter